package com.duoec.dw.lineage.core.utils;

import com.duoec.dw.lineage.dto.TableFieldDependencyDto;
import com.duoec.dw.lineage.dto.TableFieldLineageDto;
import com.duoec.dw.lineage.dto.TableLineageDto;
import org.springframework.util.CollectionUtils;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author xuwenzhen
 */
public class LineageMergeUtils {
    /**
     * 添加或合并血缘关系，如果当前集合中存在，则进行合并
     *
     * @param lineages 当前的血缘关系集合
     * @param dto      需要添加进去的血缘关系
     */
    public static void addOrMerge(List<TableLineageDto> lineages, TableLineageDto dto) {
        if (dto == null) {
            return;
        }
        Optional<TableLineageDto> lineageOpt = lineages.stream()
                .filter(table -> table.equals(dto)).findFirst();
        if (!lineageOpt.isPresent()) {
            AnalyserUtils.mergeDependency(dto);
            lineages.add(dto);
            return;
        }

        TableLineageDto lineage = lineageOpt.get();
        //合并
        LinkedHashSet<TableFieldDependencyDto> globalDependencies = lineage.getDependencies();
        if (!CollectionUtils.isEmpty(globalDependencies)) {
            //放回字段里去
            lineage.getFields().forEach(field -> {
                LinkedHashSet<TableFieldDependencyDto> fieldDependencies = field.getDependencies();
                if (fieldDependencies == null) {
                    field.setDependencies(globalDependencies);
                } else {
                    fieldDependencies.addAll(globalDependencies);
                }
            });
        }

        Map<String, TableFieldLineageDto> fieldMap = lineage.getFields()
                .stream()
                .collect(Collectors.toMap(TableFieldLineageDto::getColName, field -> field));

        LinkedHashSet<TableFieldDependencyDto> newGlobalDependencies = dto.getDependencies();
        dto.getFields().forEach(f -> {
            TableFieldLineageDto field = fieldMap.get(f.getColName());
            if (field == null) {
                return;
            }
            LinkedHashSet<TableFieldDependencyDto> fieldDependencies = field.getDependencies();
            if (fieldDependencies == null) {
                fieldDependencies = new LinkedHashSet<>();
                field.setDependencies(fieldDependencies);
            }
            if (newGlobalDependencies != null) {
                fieldDependencies.addAll(newGlobalDependencies);
            }
            LinkedHashSet<TableFieldDependencyDto> dependencies = f.getDependencies();
            if (dependencies != null) {
                fieldDependencies.addAll(dependencies);
            }
        });
        AnalyserUtils.mergeDependency(lineage);
    }
}
